package logic

import (
	"GoExample/traning/user/rpc/userclient" // 导入用户RPC服务的客户端代码，用于调用底层RPC接口
	"context"                               // 上下文包，用于传递请求的生命周期信息（如超时控制、请求追踪等）

	"GoExample/traning/user/api/internal/svc"   // 导入服务上下文包，包含当前API服务依赖的所有资源（如RPC客户端实例、配置等）
	"GoExample/traning/user/api/internal/types" // 导入API层的类型定义，包含前端请求（UserReq）和响应（UserResp）的数据结构

	"github.com/zeromicro/go-zero/core/logx" // go-zero框架的日志组件，用于输出结构化日志（支持上下文关联、级别控制等）
)

// UserLogic 封装用户查询相关的业务逻辑处理
// 作为API层与RPC层之间的桥梁，负责接收前端请求、调用RPC服务、处理结果并返回给前端
type UserLogic struct {
	logx.Logger                     // 嵌入logx.Logger，使当前结构体可直接使用日志方法（如Info、Error等）
	ctx         context.Context     // 上下文对象，贯穿整个请求生命周期，用于传递超时信号、元数据等
	svcCtx      *svc.ServiceContext // 服务上下文指针，存储当前服务的所有依赖资源（如用户RPC客户端、数据库连接等）
}

// NewUserLogic 初始化UserLogic实例的构造函数
// 采用依赖注入模式，将上下文和服务资源注入业务逻辑处理器，确保代码低耦合、可测试
// 参数：
//
//	ctx: 前端请求的上下文，包含请求级别的控制信息（如超时设置）
//	svcCtx: 服务上下文，提供业务逻辑所需的依赖资源（如RPC客户端）
//
// 返回值：
//
//	*UserLogic: 初始化后的业务逻辑处理器实例
func NewUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLogic {
	return &UserLogic{
		Logger: logx.WithContext(ctx), // 初始化日志组件并绑定上下文，使日志能关联请求链路信息（如TraceID）
		ctx:    ctx,                   // 保存请求上下文，后续调用RPC时传递，确保超时控制一致
		svcCtx: svcCtx,                // 保存服务上下文，后续通过此获取RPC客户端等资源
	}
}

// User 处理前端的用户查询请求，是核心业务逻辑方法
// 流程：接收前端请求参数 -> 调用用户RPC服务查询数据 -> 转换RPC响应为API响应 -> 返回结果
// 参数：
//
//	req: *types.UserReq 前端传递的查询请求，包含用户ID（如{Id: "1"}）
//
// 返回值：
//
//	*types.UserResp: 封装后的用户信息响应（包含ID、姓名、电话等）
//	error: 处理过程中出现的错误（如RPC调用失败、参数无效等）
func (l *UserLogic) User(req *types.UserReq) (resp *types.UserResp, err error) {
	// 1. 调用用户RPC服务的GetUser方法，查询用户详情
	// l.svcCtx.User: 从服务上下文中获取用户RPC客户端实例（已通过配置初始化）
	// l.ctx: 传递上下文，确保RPC调用的超时控制与当前请求一致
	// &userclient.GetUserReq{Id: req.Id}: 构造RPC请求参数，将API层的请求参数（req.Id）传递给RPC层
	getUserResp, err := l.svcCtx.User.GetUser(l.ctx, &userclient.GetUserReq{
		Id: req.Id,
	})
	// 2. 处理RPC调用错误（如网络异常、用户不存在等）
	if err != nil {
		// 记录错误日志（自动关联上下文信息），并将错误返回给上层（API框架会转换为HTTP错误响应）
		l.Errorf("调用用户RPC服务失败，请求ID: %s, 错误: %v", req.Id, err)
		return nil, err
	}

	// 3. 将RPC响应转换为API响应（适配前端数据格式）
	// RPC层与API层的响应结构可能存在差异，此处进行字段映射
	return &types.UserResp{
		Id:    getUserResp.Id,    // 映射用户ID
		Name:  getUserResp.Name,  // 映射用户名
		Phone: getUserResp.Phone, // 映射电话号码
	}, nil
}
